package com.coszero.utils.file

import android.content.Context
import android.os.Environment
import com.coszero.utils.utils.LogX
import java.io.File

/**
 * Desc： 文件夹路径工具类
 *
 * @author xmqian
 * Email:xmqian93@163.com
 * Date: 2020/11/6 0006 14:55
 * @link(参考链接：https://www.jianshu.com/p/e8a11d23513b)
 * @version 1
 */
object FileDirPathUtils {
    private const val TAG = "DirPathUtils"

    /**
     * 创建外部储存器中文件夹
     * 当应用被卸载的时候，目录下的文件不会被删除
     * 需要读写权限
     *
     * @param context context
     * @param sampleDir 相对路径,从外部存储器的根目录开始,例如:cacheDir = /storage/emulated/0/cacheDir
     * @return 返回已创建文件夹的绝对路径, 例如:/storage/emulated/0/cacheDir
     * @permission READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE
     */
    @JvmStatic
    fun createExternalStorageDir(context: Context, sampleDir: String): String {
        var tmpDir =
            Environment.getExternalStorageDirectory().toString() + File.separator + sampleDir
        if (!makeDir(tmpDir)) {
            LogX.w(TAG, "外部存储空间文件夹创建失败")
            //如果外部存储空间文件夹创建失败,就创建应用外部存储空间文件夹
            tmpDir = context.getExternalFilesDir(sampleDir)!!.absolutePath
            if (!makeDir(tmpDir)) {
                throw RuntimeException("create model resources dir failed :$tmpDir")
            }
        }
        LogX.i(TAG, "外部存储空间目录:$tmpDir")
        return tmpDir
    }

    /**
     * 创建外部存储空间分类文件夹
     * 当应用被卸载的时候，目录下的文件不会被删除
     * 需要读写权限
     *
     * @param context context
     * @param typeDir 文件夹类型 例如:Environment.DIRECTORY_MUSIC = /storage/emulated/0/Music
     * @param sampleDir 相对路径,从外部存储器的根目录开始,例如:cacheDir = /storage/emulated/0/Music/cacheDir
     * @return 返回已创建文件夹的绝对路径, 例如:/storage/emulated/0/Music/cacheDir
     * @permission READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE
     */
    fun createExternalStoragePublicDir(
        context: Context,
        typeDir: String?,
        sampleDir: String
    ): String {
        var tmpDir = Environment.getExternalStoragePublicDirectory(typeDir)
            .toString() + File.separator + sampleDir
        if (!makeDir(tmpDir)) {
            LogX.w(TAG, "外部存储空间分类文件夹创建失败")
            tmpDir = context.getExternalFilesDir(sampleDir)!!.absolutePath
            if (!makeDir(tmpDir)) {
                throw RuntimeException("create model resources dir failed :$tmpDir")
            }
        }
        LogX.i(TAG, "外部存储空间分类目录:$tmpDir")
        return tmpDir
    }

    /**
     * 创建应用外部存储空间分类文件夹
     * 当应用被卸载的时候，目录下的文件会被删除
     *
     * @param context context
     * @param sampleDir 相对路径,从外部存储器的根目录开始,例如:cacheDir = /storage/emulated/0/Android/data/包名/files/cacheDir/
     * @return 返回已创建文件夹的绝对路径, 例如:/storage/emulated/0/Android/data/包名/files/cacheDir/
     */
    fun createAppExternalFilesDir(context: Context, sampleDir: String?): String {
        val tmpDir = context.getExternalFilesDir(sampleDir)!!.absolutePath
        if (!makeDir(tmpDir)) {
            throw RuntimeException("create model resources dir failed :$tmpDir")
        }
        LogX.i(TAG, "应用外部存储空间分类目录:$tmpDir")
        return tmpDir
    }

    /**
     * 创建应用外部存储空间缓存文件夹
     * 当应用被卸载的时候，目录下的文件会被删除
     *
     * @param context context
     * @param sampleDir 相对路径,从外部存储器的根目录开始,例如:cacheDir = /storage/emulated/0/Android/data/包名/cache/cacheDir/
     * @return 返回已创建文件夹的绝对路径, 例如:/storage/emulated/0/Android/data/包名/cache/cacheDir/
     */
    fun createAppExternalCacheDir(context: Context, sampleDir: String): String {
        val tmpDir = context.externalCacheDir!!.absolutePath + File.separator + sampleDir
        if (!makeDir(tmpDir)) {
            throw RuntimeException("create model resources dir failed :$tmpDir")
        }
        LogX.i(TAG, "应用外部存储空间缓存目录:$tmpDir")
        return tmpDir
    }


    /**
     * 创建应用内部缓存目录
     * 应用内部存储空间（数据文件私有，外部程序无法访问）
     * 如果系统存储空间较少时，系统会自动删除这个目录下的文件。官方建议超过 1 MB 的文件最后不要存储到这个路径下
     *
     * @param context context
     * @param sampleDir 相对路径,从外部存储器的根目录开始,例如:cacheDir = /data/data/包名/cache/cacheDir/
     * @return 返回已创建文件夹的绝对路径, 例如:/data/data/包名/cache/cacheDir/
     */
    fun createAppCacheDir(context: Context, sampleDir: String): String {
        val tmpDir = context.cacheDir.absolutePath + File.separator + sampleDir
        if (!makeDir(tmpDir)) {
            throw RuntimeException("create model resources dir failed :$tmpDir")
        }
        LogX.i(TAG, "应用内部存储空间缓存目录:$tmpDir")
        return tmpDir
    }

    /**
     * 创建应用内部文件目录
     * 应用内部存储空间（数据文件私有，外部程序无法访问）
     * 应用被卸载的时候，该目录下的文件也会跟着被删除
     * 不同于 cache 目录，系统存储空间不足时不会删除该目录
     * 访问改路径的方法
     * name:     文件名
     * mode:     读/写模式。默认为 Context.MODE_PRIVATE = 0
     * context.openFileInput(String name, int mode);    // 读
     * context.openFileOutput(String name, int mode);   // 写
     *
     * @param context context
     * @param sampleDir 相对路径,从外部存储器的根目录开始,例如:cacheDir =/data/data/包名/files/cacheDir/
     * @return 返回已创建文件夹的绝对路径, 例如:/data/data/包名/files/cacheDir/
     */
    fun createAppFilesDir(context: Context, sampleDir: String): String {
        val tmpDir = context.filesDir.absolutePath + File.separator + sampleDir
        if (!makeDir(tmpDir)) {
            throw RuntimeException("create model resources dir failed :$tmpDir")
        }
        LogX.i(TAG, "应用内部存储空间文件目录:$tmpDir")
        return tmpDir
    }

    /**
     * 判断是否有该文件夹,没有则创建文件夹
     *
     * @param dirPath 文件路径
     * @return 是否有该文件路径
     */
    fun makeDir(dirPath: String): Boolean {
        val dirFile = File(dirPath)
        return makeDir(dirFile)
    }

    @JvmStatic
    fun makeDir(dirPath: File): Boolean {
        return if (!dirPath.exists()) {
            dirPath.mkdirs()
        } else {
            true
        }
    }
}
